package common

import (
	"strconv"
	"strings"
)

var DefaultPorts []int = []int{21, 22, 80, 81, 135, 139, 443, 445, 1433, 1521, 3306, 5432, 6379, 7001, 8000, 8080, 8089, 9000, 9200, 11211, 27017}

// 定义 用 文字 设置默认端口
var PortGroup = map[string]string{
	"ftp":         "21",
	"ssh":         "22",
	"findnet":     "135",
	"netbios":     "139",
	"smb":         "445",
	"mssql":       "1433",
	"oracle":      "1521",
	"mysql":       "3306",
	"rdp":         "3389",
	"psql":        "5432",
	"redis":       "6379",
	"fcgi":        "9000",
	"mem":         "11211",
	"mgo":         "27017",
	"ms17010":     "445",
	"cve20200796": "445",
	"service":     "21,22,135,139,445,1433,1521,3306,3389,5432,6379,9000,11211,27017",
	"db":          "1433,1521,3306,5432,6379,11211,27017",
	"web":         "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10250,12018,12443,14000,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,21000,21501,21502,28018,20880",
	"all":         "1-65535",
	"main":        "21,22,80,81,135,139,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017",
}

func ParsePort(ports string) (scanPorts []int) {
	if ports == "" {
		return DefaultPorts
	}

	slicePorts := strings.Split(ports, ",")
	for _, port := range slicePorts {
		// 并删除所有前导和尾随空格
		port = strings.TrimSpace(port)
		if port == "" {
			continue
		}

		if PortGroup[port] != "" {
			port = PortGroup[port]
			scanPorts = append(scanPorts, ParsePort(port)...)
			continue
		}

		upper := port
		if strings.Contains(port, "-") {
			portRanges := strings.Split(port, "-")
			if len(portRanges) < 2 {
				continue
			}

			startPort, _ := strconv.Atoi(portRanges[0])
			endPort, _ := strconv.Atoi(portRanges[1])
			if startPort < endPort {
				port = portRanges[0]
				upper = portRanges[1]
			} else {
				port = portRanges[1]
				upper = portRanges[0]
			}
		}
		start, _ := strconv.Atoi(port)
		end, _ := strconv.Atoi(upper)
		if start < 1 {
			start = 1
		}
		if end > 65535 {
			end = 65535
		}
		for i := start; i <= end; i++ {
			scanPorts = append(scanPorts, i)
		}
	}
	scanPorts = removeDuplicate(scanPorts)
	return scanPorts
}

// 删除重复端口
func removeDuplicate(old []int) []int {
	result := []int{}
	temp := map[int]struct{}{}
	for _, item := range old {
		if _, ok := temp[item]; !ok {
			temp[item] = struct{}{}
			result = append(result, item)
		}
	}
	return result
}
